﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using HWEngine.Generators;

namespace HWEngine
{
	public class Document
	{
		private HWGenerator _hwgen;
		private RtfText _rtfText;
		private LetterSetRepository _fonts;
		private RectangleF _pageBounds;
		private RectangleF _listBounds;
		private int _margins = 30;
		private int _pageWidth = 800;
		private int _pageHeight = 1000;
		private int _pagesCount;
		private int _printingPage;

		public Document(LetterSetRepository fonts, RtfText rtf)
		{
			_fonts = fonts;
			RtfText = rtf;
			Renderer = new HWGenerator(Fonts, PageBounds);
			Renderer.IsolateSmileys = true;
			CalculatePageLayout();
		}

		public RtfText RtfText
		{
			get { return _rtfText; }
			set { _rtfText = value; }
		}

		public int PagesCount
		{
			get { return _pagesCount; }
			set { _pagesCount = value; }
		}

		public RectangleF ListBounds
		{
			get { return _listBounds; }
		}

		public HWGenerator Renderer
		{
			get { return _hwgen; }
			set { _hwgen = value; }
		}

		public RectangleF PageBounds
		{
			get { return _pageBounds; }
			set { _pageBounds = value; }
		}

		public LetterSetRepository Fonts
		{
			get { return _fonts; }
		}

		private void CalculatePageLayout()
		{
			PageBounds = new RectangleF(_margins, _margins, _pageWidth, _pageHeight);
			_listBounds = new RectangleF(_margins - 15, _margins - 15, _pageWidth + 15, _pageHeight + 15);
		}

		public void Render(Graphics graphics, RectangleF viewPort)
		{
			graphics.Clear(Color.Gray);
			//Draw Text
			Renderer.PageBounds = PageBounds;
			Renderer.BeginRender(RtfText);
			int pageNum = 0;

			while (Renderer.HasMorePages)
			{
				var graphContainer = graphics.BeginContainer();
				graphics.SmoothingMode = SmoothingMode.HighQuality;
				graphics.TranslateTransform(-viewPort.Left, -viewPort.Top + pageNum * ListBounds.Bottom);

				//Draw page
				graphics.FillRectangle(Brushes.White, ListBounds);
				graphics.DrawRectangle(Pens.Black, ListBounds.Left, ListBounds.Top, ListBounds.Width, ListBounds.Height);

				Renderer.RenderPage(w => w.Draw(graphics));

				graphics.EndContainer(graphContainer);
				pageNum++;
			}
			PagesCount = pageNum;
		}

		public void BeginPrinting()
		{
			_printingPage = 0;
		}

		public void PrintHandler(object sender, PrintPageEventArgs ev)
		{
			if (_rtfText != null)
			{
				var pageBounds = new Rectangle(
					(int)ev.Graphics.VisibleClipBounds.Left + _margins,
					(int)ev.Graphics.VisibleClipBounds.Top + _margins,
					(int)ev.Graphics.VisibleClipBounds.Width - _margins * 2,
					(int)ev.Graphics.VisibleClipBounds.Height - _margins * 2);

				_hwgen.PageBounds = pageBounds;

				if (_printingPage == 0)
				{
					// Reset hash for recalculate pages.
					_rtfText.ResetHash();
					_hwgen.BeginRender(_rtfText);
				}

				ev.Graphics.SmoothingMode = SmoothingMode.HighQuality;
				_hwgen.RenderPage(w => w.Draw(ev.Graphics));

				ev.HasMorePages = _hwgen.HasMorePages;
				_printingPage++;
			}
		}

		public void ExportToSvg(string fileName)
		{
			Renderer.PageBounds = PageBounds;
			var svg = _hwgen.RenderToSvg(_rtfText);
			svg.Save(fileName);
		}
	}
}
